package org.foreningsgatan.modular.terrain;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Set;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.foreningsgatan.modular.terrain.generator.LayerGenerator;
import org.foreningsgatan.modular.terrain.model.Layer;
import org.foreningsgatan.modular.terrain.model.SimpleMap;

/**
 * 
 * Copyright (c) 2008 Joakim Back
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 * @author Joakim Back
 *
 */
public class ManualTestLayers {
	static private int TILE_SIZE = 32;
	
	static private int MAP_SIZE = 8;
	
	class DrawLayersComponent extends Component {
		private static final long serialVersionUID = 8044337070069491754L;
		
		private Set<Layer> layers;
		
		private ImageGenerator imageGenerator = new ImageGenerator(TILE_SIZE);
		
		public DrawLayersComponent(Set<Layer> layers) {
			this.layers = layers;
			
			this.setPreferredSize(new Dimension(400, 600));
		}
		
		public void drawLayers(Graphics g) {
			int c = 0;
			
			for (Layer layer: layers) {
				c++;
				
				if (c != 3) continue;
				
				int size = layer.getSize();
				
				int gridSize = size * TILE_SIZE;
				
				double offsetX = (double) (getWidth() - gridSize) / 2;
				
				double offsetY = (double) (getHeight() - gridSize) / 2;
				
				for (int y = 0; y < size; y++) {
					for (int x = 0; x < size; x++) {
						int px = (int) ((x * TILE_SIZE) + offsetX); 
						int py = (int) ((y * TILE_SIZE) + offsetY);
						
						BufferedImage image = imageGenerator.generateImage((Integer) layer.getObject(), 
								layer.get(x - 1, y - 1), 
								layer.get(x, y - 1), 
								layer.get(x - 1, y), 
								layer.get(x, y));
						
						g.drawImage(image, px, py, null);
						
						g.setColor(Color.GRAY);
						g.drawLine(px, py, px + TILE_SIZE, py);
						g.drawLine(px, py, px, py + TILE_SIZE);
					}
				}
			}
		}
		
		public void paint(Graphics g) {
			g.setColor(Color.BLACK);
			g.fillRect(0, 0, getWidth(), getHeight());
			
			drawLayers(g);
		}
	}
	
	class DrawSimpleMapComponent extends Component {
		private static final long serialVersionUID = -1425985760074080952L;
		
		private SimpleMap map;
		
		public DrawSimpleMapComponent(SimpleMap map) {
			this.map = map;
			
			this.setPreferredSize(new Dimension(400, 600));
		}
		
		private void drawMap(Graphics g) {
			int size = map.getSize();
			
			int gridSize = size * TILE_SIZE;
			
			double offsetX = (double) (getWidth() - gridSize) / 2;
			
			double offsetY = (double) (getHeight() - gridSize) / 2;
			
			for (int y = 0; y < size; y++) {
				for (int x = 0; x < size; x++) {
					int px = (int) ((x * TILE_SIZE) + offsetX); 
					int py = (int) ((y * TILE_SIZE) + offsetY);
					
					/* Draw Tile */
					
					Integer i = (Integer) map.get(x, y);
					
					if (i != null) {
						g.setColor(ImageGenerator.getColor(i));
						g.fillRect(px, py, TILE_SIZE, TILE_SIZE);
					}
					
					g.setColor(Color.GRAY);
					g.drawLine(px, py, px + TILE_SIZE, py);
					g.drawLine(px, py, px, py + TILE_SIZE);
				}
			}
			
			/* Draw Edge Lines */
			
			int minX = (getWidth() - gridSize) / 2;
			int maxX = (getWidth() + gridSize) / 2;
			int minY = (getHeight() - gridSize) / 2;
			int maxY = (getHeight() + gridSize) / 2;
			
			g.drawLine(minX, maxY, maxX, maxY);
			g.drawLine(maxX, minY, maxX, maxY);
		}

		public void paint(Graphics g) {
			g.setColor(Color.BLACK);
			g.fillRect(0, 0, getWidth(), getHeight());
			
			drawMap(g);
		}
	}
	
	private SimpleMap buildMap(int size) {
		SimpleMap map = new SimpleMap(size);
		
		double diagonal = Math.sqrt(size * size + size * size) / 2;
		
		for (int y = 0; y < size; y++) {
			for (int x = 0; x < size; x++) {
				int dx = x - (size / 2);
				int dy = y - (size / 2);
				
				double distance = Math.sqrt(dx * dx + dy * dy);
				
				Integer i = ImageGenerator.COLORS.length - (int) (distance * (ImageGenerator.COLORS.length) / diagonal) - 1;
				
				map.set(x, y, i);
			}
		}
		
		return map;
	}
	
	public ManualTestLayers() {
		SimpleMap simpleMap = buildMap(MAP_SIZE);
		
		Set<Layer> layers = LayerGenerator.generateLayers(simpleMap);
		
		/* Content Pane */
		
		JPanel p = new JPanel();
		p.setLayout(new BoxLayout(p, BoxLayout.LINE_AXIS));
		p.add(new DrawSimpleMapComponent(simpleMap));
		p.add(new DrawLayersComponent(layers));
		
		/* Display */
		
		JFrame frame = new JFrame(this.getClass().getSimpleName());
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().add(p);
		frame.pack();
		frame.setVisible(true);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new ManualTestLayers();
	}
}
